package com.leenmvc.core.dao.communal;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * 专门用于事务管理的类
 *
 */
public class TransactionManager {

    /**
     * 本地线程变量，记录当前线程事务状态
     * 1 事务状态
     * 0 非事务状态
     *
     */
    public static ThreadLocal<Integer> transLocal = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return 0;
        }
    };

    /**
     * 如果一个线程事务状态为开启的情况下，会将事务占用的连接存放在下列的hashmap中
     */
    private static Map<Long, Map<DataSource, Connection>> connectionMap = new HashMap<>();

    public static void setTrans(Integer trans) {
        transLocal.set(trans);
    }

    public static Integer getTrans() {
        return transLocal.get();
    }

    public static boolean transExist() {
        try {
            Integer trans = transLocal.get();
            if(trans == null) return false;
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 提交事务
     *
     */
    public static void commit() {
        long threadId = Thread.currentThread().getId();
        Map<DataSource, Connection> connections = connectionMap.get(threadId);
        for(DataSource dataSourceName: connections.keySet()) {
            try {
                connections.get(dataSourceName).commit();
                connections.get(dataSourceName).close();
            } catch (SQLException e) {
                rollBack();
            }
        }
        connectionMap.remove(threadId);
    }

    /**
     * 回滚事务
     *
     */
    public static void rollBack() {
        long threadId = Thread.currentThread().getId();
        Map<DataSource, Connection> connections = connectionMap.get(threadId);
        if(connections == null) {
            TransactionManager.setTrans(0);
            return;
        }
        for(DataSource dataSourceName: connections.keySet()) {
            try {
                connections.get(dataSourceName).rollback();
                connections.get(dataSourceName).close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        connectionMap.remove(threadId);
        TransactionManager.setTrans(0);
    }

    /**
     * 添加一个连接到connectionMap, 一个连接池对应一个连接
     *
     * @param connection
     */
    public static void addConnection(DataSource dataSource, Connection connection) {
        long threadId = Thread.currentThread().getId();
        Map<DataSource, Connection> connections = connectionMap.get(threadId);
        if(connections == null) {
            connections = new HashMap<>();
            connections.put(dataSource, connection);
        } else {
            connections.put(dataSource, connection);
        }
        connectionMap.put(threadId, connections);
    }

    /**
     * 获取本次线程的数据库连接
     *
     * @return
     */
    public static Connection getConnection(DataSource dataSource) {
        long threadId = Thread.currentThread().getId();
        if(connectionMap.get(threadId) == null) {
            return null;
        }
        return connectionMap.get(threadId).get(dataSource);
    }


}
